/**
 * Copyright (c) 2021-2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Autogenerated file -- DO NOT EDIT!

#ifndef ES2PANDA_COMPILER_GEN_SIGNATURES_H
#define ES2PANDA_COMPILER_GEN_SIGNATURES_H

#include "util/diagnosticEngine.h"
#include "util/ustring.h"
#include "util/language.h"

#include <optional>

namespace ark::es2panda::compiler {
class Signatures {
public:
    explicit Signatures() = delete;

    // Defines
% Signatures::DEFINES.each do |ref, define|
%   if define.comment
    static constexpr std::string_view <%= ref %> = "<%= define.name %>";  // <%= define.comment %>
%   else
    static constexpr std::string_view <%= ref %> = "<%= define.name %>";
%   end
% end

    // Primitive types
% Signatures::PRIMITIVES.each do |ref, name|
    static constexpr std::string_view <%= ref %> = "<%= name %>";
% end

    // TypeDescriptor primitives
% Signatures::TYPEDESCRIPTORS.each do |ref, name|
    static constexpr std::string_view <%= ref %> = "<%= name %>";
% end

    // Builtin classes
% Signatures::BUILTINS.each do |ref, desc|
    static constexpr std::string_view <%= ref %>_CLASS = "<%= desc[1] %>";
% end

    // Builtins
% Signatures::BUILTINS.each do |ref, desc|
    static constexpr std::string_view <%= ref %> = "<%= desc[0] %>";
% end

    // Builtin signatures
% Signatures::SIGNATURES.each do |ref, name|
    static constexpr std::string_view <%= ref %> = "<%= name %>";
% end

    class Dynamic {
    public:
        static bool IsSupported([[maybe_unused]] Language lang)
        {
% Signatures::DYNAMIC.each do |lang, data|
            if (lang.GetId() == Language::Id::<%= lang.upcase %>) {
                return true; // NOLINT(readability-simplify-boolean-expr)
            }
% end
            return false;
        }

        static std::string_view Type(Language lang)
        {
            ES2PANDA_ASSERT(IsSupported(lang));
% Signatures::DYNAMIC.each do |lang, data|
            if (lang.GetId() == Language::Id::<%= lang.upcase %>) {
                return <%= data.dynamic_class %>;
            }
% end
            ES2PANDA_UNREACHABLE();
        }

        static std::string_view CallClass(Language lang)
        {
            ES2PANDA_ASSERT(IsSupported(lang));
% Signatures::DYNAMIC.each do |lang, data|
            if (lang.GetId() == Language::Id::<%= lang.upcase %>) {
                return <%= data.call_class.name %>;
            }
% end
            ES2PANDA_UNREACHABLE();
        }

        static std::string_view InitCallClassBuiltin(Language lang)
        {
            ES2PANDA_ASSERT(IsSupported(lang));
% Signatures::DYNAMIC.each do |lang, data|
            if (lang.GetId() == Language::Id::<%= lang.upcase %>) {
                return <%= data.call_class.init_builtin %>;
            }
% end
            ES2PANDA_UNREACHABLE();
        }

        static std::string_view NewClass(Language lang)
        {
            ES2PANDA_ASSERT(IsSupported(lang));
% Signatures::DYNAMIC.each do |lang, data|
            if (lang.GetId() == Language::Id::<%= lang.upcase %>) {
                return <%= data.new_class.name %>;
            }
% end
            ES2PANDA_UNREACHABLE();
        }

        static std::string_view InitNewClassBuiltin(Language lang)
        {
            ES2PANDA_ASSERT(IsSupported(lang));
% Signatures::DYNAMIC.each do |lang, data|
            if (lang.GetId() == Language::Id::<%= lang.upcase %>) {
                return <%= data.new_class.init_builtin %>;
            }
% end
            ES2PANDA_UNREACHABLE();
        }

        static std::string_view LoadModuleBuiltin(Language lang)
        {
            ES2PANDA_ASSERT(IsSupported(lang));
% Signatures::DYNAMIC.each do |lang, data|
            if (lang.GetId() == Language::Id::<%= lang.upcase %>) {
                return <%= data.module_class.load_builtin %>;
            }
% end
            ES2PANDA_UNREACHABLE();
        }

        static std::optional<Language> LanguageFromType(std::string_view assemblerName)
        {
% Signatures::DYNAMIC.each do |lang, data|
            if (assemblerName == <%= data.dynamic_class %>) {
                return Language(Language::Id::<%= lang.upcase %>);
            }
% end
            return {};
        }

        static std::string_view GetUndefinedBuiltin(Language lang)
        {
            ES2PANDA_ASSERT(IsSupported(lang));
% Signatures::DYNAMIC.each do |lang, data|
            if (lang.GetId() == Language::Id::<%= lang.upcase %>) {
                return <%= data.builtins.get_undefined %>;
            }
% end
            ES2PANDA_UNREACHABLE();
        }

        static std::string_view GetNullBuiltin(Language lang)
        {
            ES2PANDA_ASSERT(IsSupported(lang));
% Signatures::DYNAMIC.each do |lang, data|
            if (lang.GetId() == Language::Id::<%= lang.upcase %>) {
                return <%= data.builtins.get_null %>;
            }
% end
            ES2PANDA_UNREACHABLE();
        }

% def generate(attr, pref)
%   builtins = Hash.new()
%   Signatures::DYNAMIC.each do |lang, data|
%     data.builtins[attr].each do |builtin_data|
%       builtins[builtin_data.type] = [] unless builtins.key?(builtin_data.type)
%       builtins[builtin_data.type].append([lang, builtin_data.builtin])
%     end
%   end
%   res = ''
%   builtins.each do |type, data|
%     res += "\n"
%     res += "        static std::string_view #{pref}#{type.capitalize}Builtin(Language lang)\n"
%     res += "        {\n"
%     data.each do |builtin_data|
%       (lang, builtin) = builtin_data
%       res += "            if (lang.GetId() == Language::Id::#{lang.upcase}) {\n"
%       res += "                return #{builtin};\n"
%       res += "            }\n"
%     end
%     res += "              ES2PANDA_UNREACHABLE();\n"
%     res += "        }"
%   end
% res
% end
<%= generate(:new, 'New') %>
<%= generate(:get_value, 'Get') %>
<%= generate(:get_property, 'GetProperty') %>
<%= generate(:set_property, 'SetProperty') %>
<%= generate(:get_element, 'GetElement') %>
<%= generate(:set_element, 'SetElement') %>

    };
};
}  // namespace ark::es2panda::compiler

#endif
